import sys,os,cgi,time
sys.path.insert(0, os.path.split(sys.path[0])[0])

query = os.getenv("QUERY_STRING",'') 
kwargs = cgi.parse_qs(query)
run_profiler = int(kwargs.get('profile',['0'])[0])

def main():
	import cnd
	import job
	import perf
	import res
	
	import re

	def b(x):
		if x:
			return "<td bgcolor=#00FF00><pre>YES</pre></td>"
		else:
			return "<td bgcolor=#FF0000><pre>NO</pre></td>"

	def iso(d):
		return '-'.join([d[:4],d[4:6],d[6:8]])

	def hms(s):
		if s<0:
			return "-"
		else:
			return "%d:%02d:%02d" % (int(s/3600),int(s%3600/60),int(s%60))

	def time_str(t):
		t=min(t,60*60*24-1)
		t=max(t,-60*60*24+1)
		if t<=-60:
			sign='-'
		else:
			sign=''
		return sign+time.strftime("%H:%M",time.gmtime(abs(t)))

	query = os.getenv("QUERY_STRING",'') 
	kwargs = cgi.parse_qs(query)
	date = kwargs.get('date',[time.strftime("%Y%m%d")])[0]
	tags = [t.lower() for t in re.split("\s+",kwargs.get('tags',[''])[0]) if t]
	job_name = kwargs.get('job',[''])[0]
	date_iso = iso(date)

	j = job.Job(job_name,date,fake=True)

	if False:
		print "HTTP/1.1 200 ok"
		print "Content-Type: text/html"     # HTML is following
		print
		print "<title>%s %s</title>" % (job_name,date_iso)
		print """<html><head>
		<STYLE>
		<!--
		a {text-decoration:none}
		//-->
		</STYLE>
		</head>"""
	else:
		import head
		head.header()

	print "<body>"

	def force(kind,label='force',remove=False):
		if remove:
			rem="&remove=1"
		else:
			rem=""
		return '<a href="force.py?date=%s&job=%s&kind=%s%s">%s</a>' % (date,job_name,kind,rem,label)

	# date navigation v2
	print '<table border="0" cellspacing="1" cellpadding="5"><tr>'
	dates_per_row=11
	for i,d in enumerate(cnd.dates()):
		bt = dict([(k,len(v)) for k,v in cnd.by_type(d).items()])
		if cnd.exists(job_name+'.ok',d): color='#00FF00'
		elif cnd.exists(job_name+'.ignore',d): color='#EEEEEE'
		elif cnd.exists(job_name+'.error',d): color='#FF0000'
		elif cnd.exists(job_name+'.order',d): color='#FFFF00'
		elif j.should_be_ordered(d): color='#00FFFF'
		else: color='#FFFFFF'
		stat = "%d:%d:%d:%d" % (int(j.should_be_ordered(d)),int(cnd.exists(job_name+'.order',d)),int(cnd.exists(job_name+'.ok',d)),int(cnd.exists(job_name+'.error',d)))
		print """<th bgcolor=%s><a href="job.py?date=%s&job=%s">%s</a><br>%s</th>""" % (color,d,job_name,iso(d),stat)
		if i%dates_per_row==dates_per_row-1:
			print "</tr><tr>"
	print "</tr></table>"

	# header
	flow_a = '<a href="flow.py?date=%s&job=%s">flow</a>' % (date,job_name)
	perf_a = '<a href="perf.py?job=%s">performance</a>' % (job_name)
	list_a = '<a href="list.py?date=%s&job=%s&status=order">list</a>' % (date,job_name)
	print """<h1><a href="status.py?date=%s">%s</a> %s (%s, %s, %s)</h1>""" % (date,date_iso,job_name,flow_a,perf_a,list_a)

	print "<h2>Meta:</h2>"
	print "<table>"
	if j.hint:
		print "<tr><td><pre><b>hint</b></pre></td><td><pre>%s</pre></td></tr>" % j.hint
	if j.tags:
		tags_str = " ".join(["""<a href="status.py?date=%s&tags=%s">%s</a> """%(date,t,t) for t in j.tags])
		print "<tr><td><pre><b>tags</b></pre></td><td><pre>%s</pre></td></tr>" % tags_str
	print "</table>"

	print "<h2>Status:</h2>"
	print "<table>"
	for c in sorted(cnd.list(date,job_name+'.')):
		if c==job_name+'.ok':
			color='bgcolor=#00FF00'
		elif c==job_name+'.error':
			color='bgcolor=#FF0000'
		elif c==job_name+'.ignore':
			color='bgcolor=#EEEEEE'
		elif c.endswith('.rerun') or c.endswith('.normal') or c.endswith('.unlock') or c.endswith('.unstop'):
			color='bgcolor=#FFFF00'
		elif c.endswith('.stop') or c.endswith('.continue') or c.endswith('.restart') or c.endswith('.force'):
			color='bgcolor=#00FFFF'
		elif c.endswith('.skip'):
			color='bgcolor=#FF00FF'
		else:
			color=""
		remove = '<a href="force.py?date=%s&job=%s&kind=%s&remove=1"><pre>remove</pre></a>' % (date,job_name,c[len(job_name)+1:])
		print "<tr><td %s><pre>%s</pre></td><td>%s</td></tr>" % (color,c,remove)
	print "</table>"

	print "<h2>Should be ordered:</h2>"
	print "<table>"
	print "<tr><td><pre>%s</pre></td>%s</tr>" % (iso(date),b(j.should_be_ordered(date)))
	print "</table>"

	print "<h2>Should run:</h2>"
	print "<table>"
	action = '<pre>'+force('order','order')+'</pre>'
	print "<tr><td><pre>order</pre></td>%s<td>%s</td></tr>" % (b(cnd.exists(j.name+".order",j.date)),action)
	action = '<pre>'+force('stop','stop')+'</pre>'
	print "<tr><td><pre>stop</pre></td>%s<td>%s</td></tr>" % (b((not cnd.exists(j.name+".stop",j.date)) and (not cnd.exists("all.stop",j.date))),action)
	action = '<pre>'+' '.join([force('rerun','rerun'),force('restart','restart'),force('continue','continue'),force('ignore','ignore'),force('forceok','forceok')])+'</pre>'
	print "<tr><td><pre>end</pre></td>%s<td>%s</td></tr>" % (b(j.end_should_run()),action)
	action = '<pre>'+force('date.force')+'</pre>'
	print "<tr><td><pre>date</pre></td>%s<td>%s</td></tr>" % (b(j.date_should_run()),action)
	action = '<pre>'+force('time.force')+'</pre>'
	print "<tr><td><pre>time</pre></td>%s<td>%s</td></tr>" % (b(j.time_should_run()),action)
	action = '<pre>'+force('cnd.force')+'</pre>'
	print "<tr><td><pre>cnd</pre></td>%s<td>%s</td></tr>" % (b(j.cnd_should_run()),action)
	action = '<pre>'+force('unlock','unlock')+'</pre>'
	print "<tr><td><pre>res</pre></td>%s<td>%s</td></tr>" % (b(j.res_should_run()),action)
	action = '<pre>'+force('test.force')+'</pre>'
	print "<tr><td><pre>test</pre></td>%s<td>%s</td></tr>" % (b(j.test_should_run()),action)
	action = '<pre>'+force('max_active.force')+'</pre>'
	print "<tr><td><pre>max_active</pre></td>%s<td>%s</td></tr>" % (b(j.max_active_should_run()),action)
	print "</table>"

	print '<h2>Conditions:</h2>'
	print '<table cellpadding="1">'
	for c,d in sorted(j.wait_for):
		print """<tr><td><pre><a href="job.py?date=%s&job=%s">%s %s</a></pre></td>%s</tr>""" % (d,c.split('.')[0],d,c,b(cnd.exists(c,d)))
	print "</table>"
	
	print "<h2>Resources:</h2>"
	print '<table cellpadding="1">'
	print '<tr><th>name</th><th>count</th><th>available</th><th>direct locks</th></tr>'
	for r,cnt in sorted(j.resources.items()):
		res_str = ""
		for r_lock in res.list(r):
			rj=r_lock.split('.')[0]
			rd=r_lock.split('.')[1]
			res_str += """<a href="job.py?date=%s&job=%s">%s</a> """ % (rd,rj,r_lock)
		print """<tr><td><pre>%s</pre></td><td><pre>%d</pre></td>%s<td><pre>%s</pre></td></tr>""" % (r,cnt,b(res.available(r,cnt)),res_str)
	print "</table>"

	print "<h2>Definition:</h2>"
	print "<pre>"
	print open(j.path,"r").read()
	print "</pre>"

	print "<h2>Steps:</h2>"
	print "<table><th><pre>name</pre></th><th><pre>kind</pre></th><th><pre>name</pre></th><th><pre>kind</pre></th>"
	for s,d in sorted(j.steps):
		skip_step = force(s+'.skip','<pre>skip</pre>')
		skip_kind = force(d['kind']+'.skip','<pre>skip</pre>')
		print "<tr><td><pre>%s</pre></td><td><pre>%s</pre></td><td>%s</td><td>%s</td></tr>" % (s,d['kind'],skip_step,skip_kind)
	print "</table>"

	print "<h2>Log:</h2>"
	print "<table>"
	if os.path.exists(j.log.path):
		for line in reversed(open(j.log.path,"r").readlines()[-100:]):
			print "<tr><td><pre>"+line.replace(";","</pre></td><td><pre>")+"</pre></td></tr>",
	print "</table>"

	def listdir(p,fn_fun=None):
		print "<pre>%s</pre>" % p
		if not os.path.exists(p):
			print "<pre>EMPTY</pre>"
			return
		print '<table cellpadding="5">'
		print '<tr><th><pre>name</pre></th><th><pre>size</pre></th><th><pre>time delta</pre></th><th><pre>created</pre></th><th><pre>modified</pre></th><th><pre>accessed</pre></th></tr>'
		for fn in sorted(os.listdir(p)):
			s = os.stat(os.path.join(p,fn))
			t_a = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(s[7])) # accessed
			t_m = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(s[8])) # modified
			t_c = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(s[9])) # created
			td = hms(s[8]-s[9])
			if fn_fun:
				fn = fn_fun(fn)
			print '<tr><td><pre>%s</pre></td><td align="right"><pre>%d</pre></td><td><pre>%s</pre></td><td><pre>%s</pre></td><td><pre>%s</pre></td><td><pre>%s</pre></td></tr>' % (fn,s[6],td,t_c,t_m,t_a)
		print '</table>'	

	runid=j.get_curr_runid()
	if runid:
		def view_log(fn):
			return '<a href="log.py?date=%s&job=%s&runid=%d&fn=%s">%s</a>' % (date,job_name,runid,fn,fn)
		print "<h3>run%d logs:</h3>"%runid
		listdir(os.path.join(j.logdir,'run%d'%runid),fn_fun=view_log) 

	print "<h2>Output:</h2>"
	listdir(j.outdir)

	# performance
	if True:
		print '<h2>Performance:</h2>'
		print '<table cellpadding="5">'
		print '<tr><td>%s</td><td>%s</td></tr>' % ('execution time [s]',perf.job_real_time(job_name,date))
		real_times = perf.job_real_times(job_name)
		if date in real_times:
			del real_times[date]
		if real_times:
			avg_real_time = max(1,int(sum(real_times.values())/len(real_times.values())))
		else:
			avg_real_time = '-'
		print '<tr><td>%s</td><td>%s</td></tr>' % ('average execution time [s]',avg_real_time)
		med_real_time=perf.med_real_time(job_name)
		print '<tr><td>%s</td><td>%s</td></tr>' % ('median execution time [s]',med_real_time)
		tf = 1.0*sum(perf.jobs_real_times(date,tags).values()) / max(1,sum(perf.med_real_times(date,tags).values()))
		pred_real_time=int(1.0*med_real_time*tf)
		print '<tr><td>%s</td><td>%s</td></tr>' % ('predicted execution time [s]',pred_real_time)

		med_start_time = time_str(perf.med_start_time(job_name))
		print '<tr><td>%s</td><td>%s</td></tr>' % ('median start time',med_start_time)
		med_end_time = time_str(perf.med_end_time(job_name))
		print '<tr><td>%s</td><td>%s</td></tr>' % ('median end time',med_end_time)
		print '</table>'

	print ".</body></html>"

if run_profiler:
	import profile
	profile.run("main()","rivulet-cgi-job.profile.stats")
else:
	main()
